home *** CD-ROM | disk | FTP | other *** search
/ Network CD 2 / Network CD - Volume 2.iso / programs / internet / tcp / amitcp / amitcp-src-22.lha / AmiTCP-2.2 / src / util / ifconfig / ifconfig.c next >
Encoding:
C/C++ Source or Header  |  1993-08-12  |  23.8 KB  |  867 lines

  1. static char rcsid[] = 
  2.   "$Id: ifconfig.c,v 2.8 1993/08/10 20:46:23 jraja Exp $";
  3. /*
  4.  * ifconfig.c --- Configure Network Interfaces
  5.  *
  6.  * Author: Pekka Pessi <Pekka.Pessi@hut.fi>
  7.  *
  8.  * Copyright © 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>
  9.  *            Helsinki University of Technology, Finland.
  10.  *            All rights reserved. 
  11.  *
  12.  * Created      : Sat May 15 04:12:15 1993 ppessi
  13.  * Last modified: Tue Aug 10 23:41:32 1993 jraja
  14.  */
  15.  
  16. static const char version[] = "$VER: ifconfig 2.0 (13.8.93)";
  17.  
  18. char copyright[] =
  19. "@(#) Copyright © 1983 The Regents of the University of California.\n"
  20.                       "All rights reserved.\n"
  21.      "Copyright © 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>\n"
  22.                       "Helsinki University of Technology, Finland.\n"
  23.                       "All rights reserved.\n";
  24.  
  25. /****** netutil.doc/ifconfig ************************************************
  26. *
  27. *  NAME
  28. *       ifconfig - configure network interface parameters
  29. *
  30. *  SYNOPSIS
  31. *       ifconfig interface address_family [address [dest_address]] [params]
  32. *       ifconfig interface [address_family]
  33. *
  34. *  DESCRIPTION
  35. *       ifconfig is used to assign an address to a network interface and/or
  36. *       configure network interface parameters.  ifconfig must be used at
  37. *       boot time to define the network address of each interface present on
  38. *       a machine.  It can also be used at other times to redefine an
  39. *       interface's address or other operating parameters.
  40. *
  41. *  PARAMETERS
  42. *       interface    A string of the unit name. The device name (e.g.
  43. *                     'a2065.device') concatenated with a slash ('/') and the
  44. *                     unit number ('11'), for example 'a2065.device/11' is a
  45. *                     legal unit name.
  46. *
  47. *       address_family 
  48. *                    Name of protocol on which naming scheme is based.  An
  49. *                     interface can receive transmissions in differing
  50. *                     protocols, each of which may require separate naming
  51. *                     schemes.  Therefore, it is necessary to specify the
  52. *                     address_family, which may affect interpretation of the
  53. *                     remaining parameters on the command line.  The only
  54. *                     address family currently supported is inet (DARPA-
  55. *                     Internet family).
  56. *
  57. *       address      Either a host name present in the host name database,
  58. *                     (SEE hosts), or a DARPA Internet address
  59. *                     expressed in Internet standard "dot notation".  The
  60. *                     host number can be omitted on 10-Mbyte/second Ethernet
  61. *                     interfaces (which use the hardware physical address),
  62. *                     and on interfaces other than the first.
  63. *
  64. *       dest_address Address of destination system.  Consists of either a
  65. *                     host name present in the host name database, hosts(4),
  66. *                     or a DARPA Internet address expressed in Internet
  67. *                     standard "dot notation".
  68. *
  69. *  SWITCHES  
  70. *       The following operating parameters can be specified:
  71. *
  72. *        up           Mark an interface "up". Enables interface after an
  73. *                     "ifconfig down."  Occurs automatically when setting the
  74. *                     address on an interface.  Setting this flag has no
  75. *                     effect if the hardware is "down".
  76. *
  77. *        down         Mark an interface "down".  When an interface is
  78. *                     marked "down", the system will not attempt to
  79. *                     transmit messages through that interface. If
  80. *                     possible, the interface will be reset to disable
  81. *                     reception as well.  This action does not
  82. *                     automatically disable routes using the interface.
  83. *
  84. *       arp           Enable the use of Address Resolution Protocol in
  85. *                     mapping between network level addresses and link-level
  86. *                     addresses (default).  
  87. *
  88. *       -arp          Disable the use of Address Resolution Protocol.
  89. *
  90. *        metric n     Set the routing metric of the interface to n,
  91. *                     default 0.  The routing metric is used by the routing
  92. *                     protocol (see gated(1m)).  Higher metrics have the
  93. *                     effect of making a route less favorable; metrics are
  94. *                     counted as additional hops to the destination network
  95. *                     or host.
  96. *
  97. *        debug        Enable driver-dependent debugging code. This usually
  98. *                     turns on extra console error logging.
  99. *
  100. *       -debug        Disable driver-dependent debugging code.
  101. *
  102. *        netmask mask (Inet only) Specify how much of the address to reserve
  103. *                     for subdividing networks into sub-networks.  mask
  104. *                     includes the network part of the local address, and the
  105. *                     subnet part which is taken from the host field of the
  106. *                     address.  mask can be specified as a single hexadecimal
  107. *                     number with a leading 0x, with a dot-notation Internet
  108. *                     address, or with a pseudo- network name listed in the
  109. *                     network table networks(4).  mask contains 1's for each
  110. *                     bit position in the 32-bit address that are to be used
  111. *                     for the network and subnet parts, and 0's for the host
  112. *                     part.  mask should contain at least the standard
  113. *                     network portion, and the subnet field should be
  114. *                     contiguous with the network portion.
  115. *
  116. *       broadcast    (Inet only) Specify the address that represents
  117. *                     broadcasts to the network.  The default broadcast
  118. *                     address is the address with a host part of all 1's.
  119. *
  120. *       The command:
  121. *
  122. *            ifconfig interface/unit
  123. *
  124. *       with no optional command arguments supplied displays the current
  125. *       configuration for interface.  If address_family is specified,
  126. *       ifconfig reports only the details specific to that address family.
  127. *
  128. *  DIAGNOSTICS
  129. *
  130. *       Messages indicating that the specified interface does not exist, the
  131. *       requested address is unknown, or the user is not privileged and
  132. *       tried to alter an interface's configuration.
  133. *
  134. *  EXAMPLES
  135. *
  136. *       ifconfig lo/0 127.0.0.1 
  137. *
  138. *               This command marks internal loopback device "UP", and
  139. *               attach an inet address 127.0.0.1 to it.
  140. *
  141. *       ifconfig cslip.device/0 inet 193.102.4.144 193.102.4.129
  142. *
  143. *               This command starts the CSLIP driver, attach an
  144. *               address 193.102.4.144 (our internet address) and a
  145. *               destination address 193.102.4.129 (the internet
  146. *               address of the host you are connecting) to it.
  147. *
  148. *       ifconfig devs:network/a2065.device/0 inet 193.124.100.64 +
  149. *       netmask 255.255.255.192 -arp
  150. *       
  151. *               This command loads an ethernet driver for the
  152. *               Commodore A2065 Ethernet adapter unit 0, marks it
  153. *               "up", disables ARP protocol for it, attaches an inet
  154. *               address 193.124.100.65 to it and sets its netmask to
  155. *               255.255.255.192.  A bitwise logical and of netmask and
  156. *               address for the interface forms a subnet address, in
  157. *               this case 193.124.100.64.  All packets aimed to hosts
  158. *               with same subnet address (that is hosts 193.124.100.64
  159. *               - 193.124.100.127) are routed to this interface.
  160. *
  161. *  SEE ALSO
  162. *       netstat, hosts, arp, "net/if.h", "net/sana2tags.h"
  163. *
  164. *****************************************************************************
  165. *
  166. */
  167.  
  168. /*
  169.  * Copyright © 1983 Regents of the University of California.
  170.  * All rights reserved.
  171.  *
  172.  * Redistribution and use in source and binary forms, with or without
  173.  * modification, are permitted provided that the following conditions
  174.  * are met:
  175.  * 1. Redistributions of source code must retain the above copyright
  176.  *    notice, this list of conditions and the following disclaimer.
  177.  * 2. Redistributions in binary form must reproduce the above copyright
  178.  *    notice, this list of conditions and the following disclaimer in the
  179.  *    documentation and/or other materials provided with the distribution.
  180.  * 3. All advertising materials mentioning features or use of this software
  181.  *    must display the following acknowledgement:
  182.  *    This product includes software developed by the University of
  183.  *    California, Berkeley and its contributors.
  184.  * 4. Neither the name of the University nor the names of its contributors
  185.  *    may be used to endorse or promote products derived from this software
  186.  *    without specific prior written permission.
  187.  *
  188.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  189.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  190.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  191.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  192.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  193.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  194.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  195.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  196.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  197.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  198.  * SUCH DAMAGE.
  199.  */
  200.  
  201. #ifdef AMIGA
  202. #if __SASC
  203. #include <proto/socket.h>
  204. #elif __GNUC__
  205. #include <inline/socket.h>
  206. #else
  207. #include <clib/socket_protos.h>
  208. #endif
  209. #define ioctl IoctlSocket
  210. #endif /* AMIGA */
  211.  
  212. #include <sys/param.h>
  213. #include <sys/socket.h>
  214. #include <sys/ioctl.h>
  215.  
  216. #include <net/if.h>
  217. #include <netinet/in.h>
  218. #include <arpa/inet.h>
  219.  
  220. #ifdef NS
  221. #define    NSIP
  222. #include <netns/ns.h>
  223. #include <netns/ns_if.h>
  224. #endif
  225.  
  226. #include <netdb.h>
  227.  
  228. #ifdef ISO
  229. #define EON
  230. #include <netiso/iso.h>
  231. #include <netiso/iso_var.h>
  232. #endif
  233.  
  234. #ifdef notyet
  235. #include <unistd.h>
  236. #endif
  237. #include <stdio.h>
  238. #include <errno.h>
  239. #include <ctype.h>
  240. #include <stdlib.h>
  241. #include <string.h>
  242.  
  243. struct    ifreq        ifr, ridreq;
  244. struct    ifaliasreq    addreq;
  245. #ifdef ISO
  246. struct    iso_ifreq    iso_ridreq;
  247. struct    iso_aliasreq    iso_addreq;
  248. #endif
  249. struct    sockaddr_in    netmask;
  250.  
  251. char    name[1024];
  252. int    flags;
  253. int    metric;
  254. int    setaddr;
  255. int    setipdst;
  256. int    doalias;
  257. int    clearaddr;
  258. int    newaddr = 1;
  259. int    s;
  260. extern    int errno;
  261.  
  262. #ifdef NS
  263. int    nsellength = 1;
  264. #endif
  265.  
  266. int    setifflags(), setifaddr(), setifdstaddr(), setifnetmask();
  267. int    setifmetric(), setifbroadaddr(), setifipdst();
  268. int    notealias(), setsnpaoffset(), setnsellength();
  269.  
  270. #define    NEXTARG        0xffffff
  271.  
  272. struct    cmd {
  273.     char    *c_name;
  274.     int    c_parameter;        /* NEXTARG means next argv */
  275.     int    (*c_func)();
  276. } cmds[] = {
  277.     { "up",        IFF_UP,        setifflags } ,
  278.     { "down",    -IFF_UP,    setifflags },
  279.     { "trailers",    -IFF_NOTRAILERS,setifflags },
  280.     { "-trailers",    IFF_NOTRAILERS,    setifflags },
  281.     { "arp",    -IFF_NOARP,    setifflags },
  282.     { "-arp",    IFF_NOARP,    setifflags },
  283.     { "debug",    IFF_DEBUG,    setifflags },
  284.     { "-debug",    -IFF_DEBUG,    setifflags },
  285.     { "alias",    IFF_UP,        notealias },
  286.     { "-alias",    -IFF_UP,    notealias },
  287.     { "delete",    -IFF_UP,    notealias },
  288. #ifdef notdef
  289. #define    EN_SWABIPS    0x1000
  290.     { "swabips",    EN_SWABIPS,    setifflags },
  291.     { "-swabips",    -EN_SWABIPS,    setifflags },
  292. #endif
  293.     { "netmask",    NEXTARG,    setifnetmask },
  294.     { "metric",    NEXTARG,    setifmetric },
  295.     { "broadcast",    NEXTARG,    setifbroadaddr },
  296.     { "ipdst",    NEXTARG,    setifipdst },
  297. #ifdef ISO
  298.     { "snpaoffset",    NEXTARG,    setsnpaoffset },
  299.     { "nsellength",    NEXTARG,    setnsellength },
  300. #endif
  301.     { 0,        0,        setifaddr },
  302.     { 0,        0,        setifdstaddr },
  303. };
  304.  
  305. int    in_status(), in_getaddr();
  306. #ifdef NS
  307. /*
  308.  * XNS support liberally adapted from
  309.  * code written at the University of Maryland
  310.  * principally by James O'Toole and Chris Torek.
  311.  */
  312. int    xns_status(), xns_getaddr();
  313. #endif
  314. #ifdef ISO
  315. int    iso_status(), iso_getaddr();
  316. #endif
  317.  
  318. /* Known address families */
  319. struct afswtch {
  320.     char *af_name;
  321.     short af_af;
  322.     int (*af_status)();
  323.     int (*af_getaddr)();
  324.     int af_difaddr;
  325.     int af_aifaddr;
  326.     caddr_t af_ridreq;
  327.     caddr_t af_addreq;
  328. } afs[] = {
  329. #define C(x) ((caddr_t) &x)
  330.     { "inet", AF_INET, in_status, in_getaddr,
  331.          SIOCDIFADDR, SIOCAIFADDR, C(ridreq), C(addreq) },
  332. #ifdef NS
  333.     { "ns", AF_NS, xns_status, xns_getaddr,
  334.          SIOCDIFADDR, SIOCAIFADDR, C(ridreq), C(addreq) },
  335. #endif
  336. #ifdef ISO
  337.     { "iso", AF_ISO, iso_status, iso_getaddr,
  338.          SIOCDIFADDR_ISO, SIOCAIFADDR_ISO, C(iso_ridreq), C(iso_addreq) },
  339. #endif
  340.     { 0,    0,        0,        0 }
  341. };
  342.  
  343. struct afswtch *afp;    /*the address family being set or asked about*/
  344.  
  345. main(argc, argv)
  346.     int argc;
  347.     char *argv[];
  348. {
  349.     int af = AF_INET;
  350.     register struct afswtch *rafp;
  351.  
  352.     if (argc < 2) {
  353.         fprintf(stderr, "usage: ifconfig interface\n%s%s%s%s%s",
  354.             "\t[ [ af ] [ address [ dest_addr ] ] [ up ] [ down ]",
  355.                 "[ netmask mask ] ]\n",
  356.             "\t[ metric n ]\n",
  357.             "\t[ trailers | -trailers ]\n",
  358.             "\t[ arp | -arp ]\n");
  359.         exit(1);
  360.     }
  361.     argc--, argv++;
  362.     strncpy(name, *argv, sizeof(name));
  363.     strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
  364.     argc--, argv++;
  365.     if (argc > 0) {
  366.         for (afp = rafp = afs; rafp->af_name; rafp++)
  367.             if (strcmp(rafp->af_name, *argv) == 0) {
  368.                 afp = rafp; argc--; argv++;
  369.                 break;
  370.             }
  371.         rafp = afp;
  372.         af = ifr.ifr_addr.sa_family = rafp->af_af;
  373.     }
  374.     s = socket(af, SOCK_DGRAM, 0);
  375.     if (s < 0) {
  376.         perror("ifconfig: socket");
  377.         exit(1);
  378.     }
  379.     if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
  380.         Perror("ioctl (SIOCGIFFLAGS)");
  381.         exit(1);
  382.     }
  383.     strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
  384.     flags = ifr.ifr_flags;
  385.     if (ioctl(s, SIOCGIFMETRIC, (caddr_t)&ifr) < 0)
  386.         perror("ioctl (SIOCGIFMETRIC)");
  387.     else
  388.         metric = ifr.ifr_metric;
  389.     if (argc == 0) {
  390.         status();
  391.         exit(0);
  392.     }
  393.     while (argc > 0) {
  394.         register struct cmd *p;
  395.  
  396.         for (p = cmds; p->c_name; p++)
  397.             if (strcmp(*argv, p->c_name) == 0)
  398.                 break;
  399.         if (p->c_name == 0 && setaddr)
  400.             p++;    /* got src, do dst */
  401.         if (p->c_func) {
  402.             if (p->c_parameter == NEXTARG) {
  403.                 (*p->c_func)(argv[1]);
  404.                 argc--, argv++;
  405.             } else
  406.                 (*p->c_func)(*argv, p->c_parameter);
  407.         }
  408.         argc--, argv++;
  409.     }
  410. #ifdef ISO
  411.     if (af == AF_ISO)
  412.         adjust_nsellength();
  413. #endif
  414. #ifdef NS
  415.     if (setipdst && af==AF_NS) {
  416.         struct nsip_req rq;
  417.         int size = sizeof(rq);
  418.  
  419.         rq.rq_ns = addreq.ifra_addr;
  420.         rq.rq_ip = addreq.ifra_dstaddr;
  421.  
  422.         if (setsockopt(s, 0, SO_NSIP_ROUTE, &rq, size) < 0)
  423.             Perror("Encapsulation Routing");
  424.     }
  425. #endif
  426.     if (clearaddr) {
  427.         int ret;
  428.         strncpy(rafp->af_ridreq, name, sizeof ifr.ifr_name);
  429.         if ((ret = ioctl(s, rafp->af_difaddr, rafp->af_ridreq)) < 0) {
  430.             if (errno == EADDRNOTAVAIL && (doalias >= 0)) {
  431.                 /* means no previous address for interface */
  432.             } else
  433.                 Perror("ioctl (SIOCDIFADDR)");
  434.         }
  435.     }
  436.     if (newaddr) {
  437.         strncpy(rafp->af_addreq, name, sizeof ifr.ifr_name);
  438.         if (ioctl(s, rafp->af_aifaddr, rafp->af_addreq) < 0)
  439.             Perror("ioctl (SIOCAIFADDR)");
  440.     }
  441.     exit(0);
  442. }
  443. #define RIDADDR 0
  444. #define ADDR    1
  445. #define MASK    2
  446. #define DSTADDR    3
  447.  
  448. /*ARGSUSED*/
  449. setifaddr(addr, param)
  450.     char *addr;
  451.     short param;
  452. {
  453.     /*
  454.      * Delay the ioctl to set the interface addr until flags are all set.
  455.      * The address interpretation may depend on the flags,
  456.      * and the flags may change when the address is set.
  457.      */
  458.     setaddr++;
  459.     if (doalias == 0)
  460.         clearaddr = 1;
  461.     (*afp->af_getaddr)(addr, (doalias >= 0 ? ADDR : RIDADDR));
  462. }
  463.  
  464. setifnetmask(addr)
  465.     char *addr;
  466. {
  467.     (*afp->af_getaddr)(addr, MASK);
  468. }
  469.  
  470. setifbroadaddr(addr)
  471.     char *addr;
  472. {
  473.     (*afp->af_getaddr)(addr, DSTADDR);
  474. }
  475.  
  476. setifipdst(addr)
  477.     char *addr;
  478. {
  479.     in_getaddr(addr, DSTADDR);
  480.     setipdst++;
  481.     clearaddr = 0;
  482.     newaddr = 0;
  483. }
  484. #define rqtosa(x) (&(((struct ifreq *)(afp->x))->ifr_addr))
  485. /*ARGSUSED*/
  486. notealias(addr, param)
  487.     char *addr;
  488. {
  489.     if (setaddr && doalias == 0 && param < 0)
  490.         bcopy((caddr_t)rqtosa(af_addreq),
  491.               (caddr_t)rqtosa(af_ridreq),
  492.               rqtosa(af_addreq)->sa_len);
  493.     doalias = param;
  494.     if (param < 0) {
  495.         clearaddr = 1;
  496.         newaddr = 0;
  497.     } else
  498.         clearaddr = 0;
  499. }
  500.  
  501. /*ARGSUSED*/
  502. setifdstaddr(addr, param)
  503.     char *addr;
  504.     int param;
  505. {
  506.     (*afp->af_getaddr)(addr, DSTADDR);
  507. }
  508.  
  509. setifflags(vname, value)
  510.     char *vname;
  511.     short value;
  512. {
  513.      if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
  514.          Perror("ioctl (SIOCGIFFLAGS)");
  515.          exit(1);
  516.      }
  517.     strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  518.      flags = ifr.ifr_flags;
  519.  
  520.     if (value < 0) {
  521.         value = -value;
  522.         flags &= ~value;
  523.     } else
  524.         flags |= value;
  525.     ifr.ifr_flags = flags;
  526.     if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)
  527.         Perror(vname);
  528. }
  529.  
  530. setifmetric(val)
  531.     char *val;
  532. {
  533.     strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  534.     ifr.ifr_metric = atoi(val);
  535.     if (ioctl(s, SIOCSIFMETRIC, (caddr_t)&ifr) < 0)
  536.         perror("ioctl (set metric)");
  537. }
  538. #ifdef ISO
  539. setsnpaoffset(val)
  540.     char *val;
  541. {
  542.     iso_addreq.ifra_snpaoffset = atoi(val);
  543. }
  544. #endif
  545. #define    IFFBITS \
  546. "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\
  547. "
  548.  
  549. /*
  550.  * Print the status of the interface.  If an address family was
  551.  * specified, show it and it only; otherwise, show them all.
  552.  */
  553. status()
  554. {
  555.     register struct afswtch *p = afp;
  556.     short af = ifr.ifr_addr.sa_family;
  557.  
  558.     printf("%s: ", name);
  559.     printb("flags", flags, IFFBITS);
  560.     if (metric)
  561.         printf(" metric %d", metric);
  562.     putchar('\n');
  563.     if ((p = afp) != NULL) {
  564.         (*p->af_status)(1);
  565.     } else for (p = afs; p->af_name; p++) {
  566.         ifr.ifr_addr.sa_family = p->af_af;
  567.         (*p->af_status)(0);
  568.     }
  569. }
  570.  
  571. in_status(force)
  572.     int force;
  573. {
  574.     struct sockaddr_in *sin;
  575.  
  576.     strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  577.     if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) {
  578.         if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
  579.             if (!force)
  580.                 return;
  581.             bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
  582.         } else
  583.             perror("ioctl (SIOCGIFADDR)");
  584.     }
  585.     sin = (struct sockaddr_in *)&ifr.ifr_addr;
  586.     printf("\tinet %s ", inet_ntoa(sin->sin_addr));
  587.     strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  588.     if (ioctl(s, SIOCGIFNETMASK, (caddr_t)&ifr) < 0) {
  589.         if (errno != EADDRNOTAVAIL)
  590.             perror("ioctl (SIOCGIFNETMASK)");
  591.         bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
  592.     } else
  593.         netmask.sin_addr =
  594.             ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
  595.     if (flags & IFF_POINTOPOINT) {
  596.         if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) {
  597.             if (errno == EADDRNOTAVAIL)
  598.                 bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
  599.             else
  600.                 perror("ioctl (SIOCGIFDSTADDR)");
  601.         }
  602.         strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  603.         sin = (struct sockaddr_in *)&ifr.ifr_dstaddr;
  604.         printf("--> %s ", inet_ntoa(sin->sin_addr));
  605.     }
  606.     printf("netmask %x ", ntohl(netmask.sin_addr.s_addr));
  607.     if (flags & IFF_BROADCAST) {
  608.         if (ioctl(s, SIOCGIFBRDADDR, (caddr_t)&ifr) < 0) {
  609.             if (errno == EADDRNOTAVAIL)
  610.                 bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
  611.             else
  612.                 perror("ioctl (SIOCGIFADDR)");
  613.         }
  614.         strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  615.         sin = (struct sockaddr_in *)&ifr.ifr_addr;
  616.         if (sin->sin_addr.s_addr != 0)
  617.             printf("broadcast %s", inet_ntoa(sin->sin_addr));
  618.     }
  619.     putchar('\n');
  620. }
  621.  
  622. #ifdef NS
  623. xns_status(force)
  624.     int force;
  625. {
  626.     struct sockaddr_ns *sns;
  627.  
  628.     close(s);
  629.     s = socket(AF_NS, SOCK_DGRAM, 0);
  630.     if (s < 0) {
  631.         if (errno == EPROTONOSUPPORT)
  632.             return;
  633.         perror("ifconfig: socket");
  634.         exit(1);
  635.     }
  636.     if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) {
  637.         if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
  638.             if (!force)
  639.                 return;
  640.             bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
  641.         } else
  642.             perror("ioctl (SIOCGIFADDR)");
  643.     }
  644.     strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
  645.     sns = (struct sockaddr_ns *)&ifr.ifr_addr;
  646.     printf("\tns %s ", ns_ntoa(sns->sns_addr));
  647.     if (flags & IFF_POINTOPOINT) { /* by W. Nesheim@Cornell */
  648.         if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) {
  649.             if (errno == EADDRNOTAVAIL)
  650.                 bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
  651.             else
  652.                 Perror("ioctl (SIOCGIFDSTADDR)");
  653.         }
  654.         strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  655.         sns = (struct sockaddr_ns *)&ifr.ifr_dstaddr;
  656.         printf("--> %s ", ns_ntoa(sns->sns_addr));
  657.     }
  658.     putchar('\n');
  659. }
  660. #endif
  661. #ifdef ISO
  662. iso_status(force)
  663.     int force;
  664. {
  665.     struct sockaddr_iso *siso;
  666.     struct iso_ifreq ifr;
  667.  
  668.     close(s);
  669.     s = socket(AF_ISO, SOCK_DGRAM, 0);
  670.     if (s < 0) {
  671.         if (errno == EPROTONOSUPPORT)
  672.             return;
  673.         perror("ifconfig: socket");
  674.         exit(1);
  675.     }
  676.     bzero((caddr_t)&ifr, sizeof(ifr));
  677.     strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
  678.     if (ioctl(s, SIOCGIFADDR_ISO, (caddr_t)&ifr) < 0) {
  679.         if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
  680.             if (!force)
  681.                 return;
  682.             bzero((char *)&ifr.ifr_Addr, sizeof(ifr.ifr_Addr));
  683.         } else {
  684.             perror("ioctl (SIOCGIFADDR_ISO)");
  685.             exit(1);
  686.         }
  687.     }
  688.     strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
  689.     siso = &ifr.ifr_Addr;
  690.     printf("\tiso %s ", iso_ntoa(&siso->siso_addr));
  691.     if (ioctl(s, SIOCGIFNETMASK_ISO, (caddr_t)&ifr) < 0) {
  692.         if (errno != EADDRNOTAVAIL)
  693.             perror("ioctl (SIOCGIFNETMASK_ISO)");
  694.     } else {
  695.         printf(" netmask %s ", iso_ntoa(&siso->siso_addr));
  696.     }
  697.     if (flags & IFF_POINTOPOINT) {
  698.         if (ioctl(s, SIOCGIFDSTADDR_ISO, (caddr_t)&ifr) < 0) {
  699.             if (errno == EADDRNOTAVAIL)
  700.                 bzero((char *)&ifr.ifr_Addr, sizeof(ifr.ifr_Addr));
  701.             else
  702.                 Perror("ioctl (SIOCGIFDSTADDR_ISO)");
  703.         }
  704.         strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  705.         siso = &ifr.ifr_Addr;
  706.         printf("--> %s ", iso_ntoa(&siso->siso_addr));
  707.     }
  708.     putchar('\n');
  709. }
  710. #endif
  711.  
  712. Perror(cmd)
  713.     char *cmd;
  714. {
  715.     extern int errno;
  716.  
  717.     fprintf(stderr, "ifconfig: ");
  718.     switch (errno) {
  719.  
  720.     case ENXIO:
  721.         fprintf(stderr, "%s: no such interface\n", cmd);
  722.         break;
  723.  
  724.     case EPERM:
  725.         fprintf(stderr, "%s: permission denied\n", cmd);
  726.         break;
  727.  
  728.     default:
  729.         perror(cmd);
  730.     }
  731.     exit(1);
  732. }
  733.  
  734. #define SIN(x) ((struct sockaddr_in *) &(x))
  735. struct sockaddr_in *sintab[] = {
  736. SIN(ridreq.ifr_addr), SIN(addreq.ifra_addr),
  737. SIN(addreq.ifra_mask), SIN(addreq.ifra_broadaddr)};
  738.  
  739. in_getaddr(s, which)
  740.     char *s;
  741. {
  742.     register struct sockaddr_in *sin = sintab[which];
  743.     struct hostent *hp;
  744.     struct netent *np;
  745.     int val;
  746.  
  747.     sin->sin_len = sizeof(*sin);
  748.     if (which != MASK)
  749.         sin->sin_family = AF_INET;
  750.  
  751.     if ((val = inet_addr(s)) != -1)
  752.         sin->sin_addr.s_addr = val;
  753.     else if (hp = gethostbyname(s))
  754.         bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length);
  755.     else if (np = getnetbyname(s))
  756.         sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
  757.     else {
  758.         fprintf(stderr, "%s: bad value\n", s);
  759.         exit(1);
  760.     }
  761. }
  762.  
  763. /*
  764.  * Print a value a la the %b format of the kernel's printf
  765.  */
  766. printb(s, v, bits)
  767.     char *s;
  768.     register char *bits;
  769.     register unsigned short v;
  770. {
  771.     register int i, any = 0;
  772.     register char c;
  773.  
  774.     if (bits && *bits == 8)
  775.         printf("%s=%o", s, v);
  776.     else
  777.         printf("%s=%x", s, v);
  778.     bits++;
  779.     if (bits) {
  780.         putchar('<');
  781.         while (i = *bits++) {
  782.             if (v & (1 << (i-1))) {
  783.                 if (any)
  784.                     putchar(',');
  785.                 any = 1;
  786.                 for (; (c = *bits) > 32; bits++)
  787.                     putchar(c);
  788.             } else
  789.                 for (; *bits > 32; bits++)
  790.                     ;
  791.         }
  792.         putchar('>');
  793.     }
  794. }
  795.  
  796. #ifdef NS
  797. #define SNS(x) ((struct sockaddr_ns *) &(x))
  798. struct sockaddr_ns *snstab[] = {
  799. SNS(ridreq.ifr_addr), SNS(addreq.ifra_addr),
  800. SNS(addreq.ifra_mask), SNS(addreq.ifra_broadaddr)};
  801.  
  802. xns_getaddr(addr, which)
  803. char *addr;
  804. {
  805.     struct sockaddr_ns *sns = snstab[which];
  806.     struct ns_addr ns_addr();
  807.  
  808.     sns->sns_family = AF_NS;
  809.     sns->sns_len = sizeof(*sns);
  810.     sns->sns_addr = ns_addr(addr);
  811.     if (which == MASK)
  812.         printf("Attempt to set XNS netmask will be ineffectual\n");
  813. }
  814. #endif
  815.  
  816. #ifdef ISO
  817. #define SISO(x) ((struct sockaddr_iso *) &(x))
  818. struct sockaddr_iso *sisotab[] = {
  819. SISO(iso_ridreq.ifr_Addr), SISO(iso_addreq.ifra_addr),
  820. SISO(iso_addreq.ifra_mask), SISO(iso_addreq.ifra_dstaddr)};
  821.  
  822. iso_getaddr(addr, which)
  823. char *addr;
  824. {
  825.     register struct sockaddr_iso *siso = sisotab[which];
  826.     struct iso_addr *iso_addr();
  827.     siso->siso_addr = *iso_addr(addr);
  828.  
  829.     if (which == MASK) {
  830.         siso->siso_len = TSEL(siso) - (caddr_t)(siso);
  831.         siso->siso_nlen = 0;
  832.     } else {
  833.         siso->siso_len = sizeof(*siso);
  834.         siso->siso_family = AF_ISO;
  835.     }
  836. }
  837.  
  838. setnsellength(val)
  839.     char *val;
  840. {
  841.     nsellength = atoi(val);
  842.     if (nsellength < 0) {
  843.         fprintf(stderr, "Negative NSEL length is absurd\n");
  844.         exit (1);
  845.     }
  846.     if (afp == 0 || afp->af_af != AF_ISO) {
  847.         fprintf(stderr, "Setting NSEL length valid only for iso\n");
  848.         exit (1);
  849.     }
  850. }
  851.  
  852. fixnsel(s)
  853. register struct sockaddr_iso *s;
  854. {
  855.     if (s->siso_family == 0)
  856.         return;
  857.     s->siso_tlen = nsellength;
  858. }
  859.  
  860. adjust_nsellength()
  861. {
  862.     fixnsel(sisotab[RIDADDR]);
  863.     fixnsel(sisotab[ADDR]);
  864.     fixnsel(sisotab[DSTADDR]);
  865. }
  866. #endif
  867.